package viroyal.com.base.activity.main;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.aiwinn.base.log.LogUtils;
import com.aiwinn.base.util.SizeUtils;
import com.aiwinn.base.util.StringUtils;
import com.aiwinn.base.widget.CameraInterfaceBak;
import com.aiwinn.base.widget.CameraSurfaceView;
import com.aiwinn.deblocks.utils.FeatureUtils;
import com.aiwinn.facedetectsdk.FaceDetectManager;
import com.aiwinn.facedetectsdk.bean.FaceBean;
import com.aiwinn.facedetectsdk.bean.UserBean;
import com.aiwinn.facedetectsdk.common.ConfigLib;
import com.aiwinn.facedetectsdk.common.Status;
import com.baidu.tts.BaiDuTtsUtil;
import com.baidu.tts.listener.OnSpeechListener;
import com.facebook.drawee.view.SimpleDraweeView;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.DefaultHandler;
import com.google.gson.Gson;
import com.hwangjr.rxbus.RxBus;
import com.suntiago.a.ChinaDateUtil;
import com.suntiago.baseui.activity.base.ActivityBase;
import com.suntiago.baseui.activity.base.AppDelegateBase;
import com.suntiago.baseui.utils.AppUtils;
import com.suntiago.baseui.utils.SPUtils;
import com.suntiago.baseui.utils.ScreenUtils;
import com.suntiago.baseui.utils.date.DateUtils;
import com.suntiago.baseui.utils.log.Slog;
import com.suntiago.network.network.ErrorCode;
import com.superluo.textbannerlibrary.TextBannerView;
import com.viroyal.monitorlib.service.MainStartService;

import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import org.kymjs.kjframe.KJDB;

import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import kotlin.jvm.internal.Intrinsics;
import pl.droidsonroids.gif.GifImageView;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import viroyal.com.base.AppConfig;
import viroyal.com.base.MyApp;
import viroyal.com.base.R;
import viroyal.com.base.activity.engineering.EngineeringListActivity;
import viroyal.com.base.adapter.ItemClassAdapter;
import viroyal.com.base.adapter.ItemNoticePagerAdapter;
import viroyal.com.base.adapter.ItemSortAdapter;
import viroyal.com.base.common.ConstantsYJ;
import viroyal.com.base.face.aiwinn.common.AttConstants;
import viroyal.com.base.face.aiwinn.face_detect.DetectPresenter;
import viroyal.com.base.face.aiwinn.face_detect.DetectView;
import viroyal.com.base.face.bean.DeviceInfo;
import viroyal.com.base.face.rsp.DeviceInfoRsp;
import viroyal.com.base.listener.OnClickEffectiveListener;
import viroyal.com.base.listener.OnSelectStudentDialogListener;
import viroyal.com.base.model.Announced;
import viroyal.com.base.model.HomeInfo;
import viroyal.com.base.model.OwnStyle;
import viroyal.com.base.model.QrCode;
import viroyal.com.base.model.Student;
import viroyal.com.base.model.Weather;
import viroyal.com.base.net.entity.IOTConfigBean;
import viroyal.com.base.net.entity.ModuleEntity;
import viroyal.com.base.net.entity.MottoItem;
import viroyal.com.base.net.entity.Timetables;
import viroyal.com.base.net.rsp.AppInfoRspS;
import viroyal.com.base.net.rsp.CountDownTimeInfoResponse;
import viroyal.com.base.net.rsp.ParentLinkStudentsResponseS;
import viroyal.com.base.util.HtmlToStringUtil;
import viroyal.com.base.util.QrCodeUtil;
import viroyal.com.base.util.Utils;
import viroyal.com.base.util.WeatherUtil;
import viroyal.com.base.widget.AutoPollRecyclerView;
import viroyal.com.base.widget.BannerView.BannerView;
import viroyal.com.base.widget.InputDialog;
import viroyal.com.base.widget.LooperLayoutManager;
import viroyal.com.base.widget.NoticeDialogFragment;
import viroyal.com.base.widget.ParentStudentDialogFragment;
import viroyal.com.base.widget.SelectStudentDialogFragment;
import viroyal.com.base.widget.SignSearchDialogFragment;
import viroyal.com.base.widget.StudentDialogFragment;
import viroyal.com.base.widget.WeatherPopwindow;
import viroyal.com.base.widget.dialog.OnDialogKeyListener;
import viroyal.com.dev.broadcast.BroadcastView;
import viroyal.com.dev.splash.ConfigDevice;

import static android.content.Context.BIND_AUTO_CREATE;


/**
 * @author chenjunwei
 * @desc 主页面UI处理
 * @date 2019/5/28
 */
public class MainDelegate extends AppDelegateBase<MainModel> implements CameraInterfaceBak.CameraStateCallBack, DetectView {
  private final String TAG = getClass().getSimpleName();
  public static final String TAG_DEBUG_FACE = "tag_debug_face";

  private List<Announced> mNoticesList = new ArrayList<>();
  private ItemNoticePagerAdapter mNoticeAdapter;

  private ItemSortAdapter itemSortAdapter;
  private List<AppInfoRspS.Apps> mAppsInfo = new ArrayList<>();

  private int mMaxClickNum = 5;
  /**
   * 记录点击次数
   */
  private long[] mHits = new long[mMaxClickNum];
  /**
   * 记录点击次数
   */
  private long[] mSignRecordHits = new long[mMaxClickNum];
  /**
   * 记录点击次数
   */
  private long[] mSyncDataHits = new long[mMaxClickNum];


  private String mPassword = "84159009";


  private ItemClassAdapter mClassAdapter;
  private List<Timetables> mClassList;
  private RecyclerView sort_list;

  @Override
  public int getRootLayoutId() {
    if (android.os.Build.MODEL.equals("T2") || android.os.Build.MODEL.equals("T3") || android.os.Build.MODEL.equals("T6")) {
      //新班牌(华瑞安)
      return R.layout.activity_main;
    } else if (android.os.Build.MODEL.equals("rk3288")) {
      //广州星马(班牌)
      return R.layout.activity_main_xm;
    }
    return R.layout.activity_main;
  }

  @Override
  public void initWidget() {
    itemSortAdapter = new ItemSortAdapter(getActivity(), mAppsInfo, this);
//    LooperLayoutManager layoutManager = new LooperLayoutManager();
//    layoutManager.setLooperEnable(true);
    sort_list = get(R.id.rv_sort_list);
    sort_list.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
//    sort_list.setLayoutManager(layoutManager);
    sort_list.setAdapter(itemSortAdapter);

    int height = ScreenUtils.getScreenHeight(getActivity()) + ScreenUtils.getDaoHangHeight(getActivity());
    int faceHeight = (int) (height * 0.25) - SizeUtils.dp2px(10);

    LinearLayout.LayoutParams cameraLp = (LinearLayout.LayoutParams) get(R.id.rl_camera).getLayoutParams();
    cameraLp.width = (int) (faceHeight);
    cameraLp.height = (int) (faceHeight);
    get(R.id.rl_camera).setLayoutParams(cameraLp);

    LinearLayout.LayoutParams qrCodeLp = (LinearLayout.LayoutParams) get(R.id.iv_qr_code).getLayoutParams();
    qrCodeLp.width = (int) (faceHeight * 0.6413);
    qrCodeLp.height = (int) (faceHeight * 0.6413);
    get(R.id.iv_qr_code).setLayoutParams(qrCodeLp);

    mClassList = new ArrayList<>();
    mClassAdapter = new ItemClassAdapter(mClassList);
    ((RecyclerView) get(R.id.rv_class_list)).setAdapter(mClassAdapter);
    ((RecyclerView) get(R.id.rv_class_list)).setLayoutManager(new GridLayoutManager(getActivity(), 1));


    RelativeLayout rlBanner = get(R.id.rl_banner);
    bannerView = new BannerView(rootView.getContext(), mNoticesList, R.layout.custom_viewpager);
    mNoticeAdapter = new ItemNoticePagerAdapter(this, mNoticesList, getActivity(), bannerView.getViewPager());
    bannerView.getViewPager().setAdapter(mNoticeAdapter);
    mNoticeAdapter.adapterNotifyDataSetChanged(mNoticesList);
    rlBanner.addView(bannerView.getBannerView());

    ((TextView) get(R.id.tv_version)).setText("Version " + AppUtils.getVersionName(getActivity()));
  }

  private void stopSpeak() {
    getActivity().runOnUiThread(() -> {
      ((ImageView) get(R.id.iv_horn)).setImageResource(R.mipmap.ic_horn4);
      isSpeech = false;
    });
  }

  private void startSpeak(int currentPos) {
    getActivity().runOnUiThread(() -> {
      currentSpeechPos = currentPos;
      isSpeech = true;
      Drawable drawable = getActivity().getResources().getDrawable(R.drawable.bg_horn);
      ((ImageView) get(R.id.iv_horn)).setImageDrawable(drawable);
      Animatable animatable = (Animatable) ((ImageView) get(R.id.iv_horn)).getDrawable();
      if (null != animatable) {
        animatable.start();
      }
    });
  }


  private boolean isSpeech = false;
  private int currentSpeechPos = 0;

  private BannerView bannerView;

  void setListener() {
    get(R.id.iv_horn).setOnClickListener(view -> {
      int currentPos = ((ViewPager) get(R.id.viewPager)).getCurrentItem();
      int realPosition = 0;
      if (null != mNoticesList && !mNoticesList.isEmpty()) {
        realPosition = currentPos % mNoticesList.size();
      }
      if (null != mNoticesList && realPosition < mNoticesList.size()) {
        if (isSpeech && realPosition == currentSpeechPos) {
          BaiDuTtsUtil.stop();
          stopSpeak();
          return;
        }
        startSpeak(realPosition);
        Announced announced = mNoticesList.get(realPosition);
        BaiDuTtsUtil.speak(announced.title + HtmlToStringUtil.replaceBlank(HtmlToStringUtil.getHtmlContent(announced.value)), new OnSpeechListener() {
          @Override
          public void onSpeechStart() {

          }

          @Override
          public void onSpeechFinish() {
            stopSpeak();
          }

          @Override
          public void onError() {
            stopSpeak();
          }
        });
      }
    });
    get(R.id.school_img).setOnClickListener(v -> {
      //所有元素左移一个位置
      System.arraycopy(mHits, 1, mHits, 0, mHits.length - 1);
      mHits[mHits.length - 1] = SystemClock.uptimeMillis();
      if (mHits[0] >= (SystemClock.uptimeMillis() - 3000)) {
        //重置点击次数
        mHits = new long[mMaxClickNum];
        InputDialog inputDialog = InputDialog.newInstance(new InputDialog.Listener() {
          @Override
          public void onNumberSelected(String item) {

          }

          @Override
          public void ok(String item) {
            if (TextUtils.equals(mPassword, item)) {
              Slog.i(TAG, "onClick:weather_img:password currect");
              //关闭监控，防杀
              Intent intent = new Intent(getActivity(), MainStartService.class);
              intent.putExtra("exit", true);
              getActivity().bindService(intent, conn, BIND_AUTO_CREATE);
              getActivity().stopService(intent);

              Intent stop = new Intent("org.sipdroid.sipua.stop_service");
              getActivity().sendBroadcast(stop);

              getActivity().finish();
            } else if (TextUtils.equals("20200202", item)) {
              //进入工程模式
              Slog.i(TAG, "onClick:into Engineering mode");
              getActivity().startActivity(new Intent(getActivity(), EngineeringListActivity.class));
            } else {
              showToast(getActivity().getString(R.string.password_error));
            }
          }
        }, "", 0);
        inputDialog.setShowBottom(true);
        inputDialog.show(getActivity().getFragmentManager(), "");
      }
    });

    get(R.id.data_layout).setOnClickListener(v -> {
      //所有元素左移一个位置
      System.arraycopy(mSyncDataHits, 1, mSyncDataHits, 0, mSyncDataHits.length - 1);
      mSyncDataHits[mSyncDataHits.length - 1] = SystemClock.uptimeMillis();
      if (mSyncDataHits[0] >= (SystemClock.uptimeMillis() - 3000)) {
        //重置点击次数
        mSyncDataHits = new long[mMaxClickNum];
        InputDialog inputDialog = InputDialog.newInstance(new InputDialog.Listener() {
          @Override
          public void onNumberSelected(String item) {

          }

          @Override
          public void ok(String item) {
            if (TextUtils.equals(mPassword, item)) {
              Slog.i(TAG, "onClick:weather_img:password currect");
              ((MainActivity) getActivity()).showResetDialog();
            } else {
              showToast(getActivity().getString(R.string.password_error));
            }
          }
        }, "", 0);
        inputDialog.setShowBottom(true);
        inputDialog.show(getActivity().getFragmentManager(), "");
      }
    });

    get(R.id.iv_qr_code).setOnClickListener(v -> {
      //所有元素左移一个位置
      System.arraycopy(mSignRecordHits, 1, mSignRecordHits, 0, mSignRecordHits.length - 1);
      mSignRecordHits[mHits.length - 1] = SystemClock.uptimeMillis();
      if (mSignRecordHits[0] >= (SystemClock.uptimeMillis() - 3000)) {
        //重置点击次数
        mSignRecordHits = new long[mMaxClickNum];
        InputDialog inputDialog = InputDialog.newInstance(new InputDialog.Listener() {
          @Override
          public void onNumberSelected(String item) {

          }

          @Override
          public void ok(String item) {
            if (TextUtils.equals(mPassword, item)) {
              Slog.i(TAG, "onClick:weather_img:password currect");
              showAllSignRecordDialogFragment();
            } else {
              showToast(getActivity().getString(R.string.password_error));
            }
          }
        }, "", 0);
        inputDialog.setShowBottom(true);
        inputDialog.show(getActivity().getFragmentManager(), "");
      }
    });

//    get(R.id.img_weather).setOnClickListener(v -> {
//      Intent intent = new Intent(getActivity(), CallActivity.class);
//      intent.putExtra("ServerAddr", "http://192.168.1.9:8080");
//      intent.putExtra("RoomName", "1");
//      getActivity().startActivity(intent);
//    });
  }

  //监控
  private boolean isBound = false;
  private ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder binder) {
      isBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
      isBound = false;
    }
  };

  @Override
  public void viewBindModel(MainModel data) {
  }

  void initDateShow() {
    String ndate = DateUtils.format(new Date(), "yyyy-MM-dd EEEE");
    String odate = ChinaDateUtil.today();
    ((TextView) get(R.id.tv_date_lunar_calendar)).setText(odate);
    ((TextView) get(R.id.tv_date_solar_calendar)).setText(ndate);
  }

  void showShortToast(int code, String msg) {
    switch (code) {
      case ErrorCode.CONNECTION_EXCEPTION:
        msg = getActivity().getString(R.string.error_connection);
        break;
      case ErrorCode.SERVER_Exception:
      case ErrorCode.SERVER_BadGateway:
        msg = getActivity().getString(R.string.error_server);
        break;
      case ErrorCode.SOCKET_TIMEOUT_Exception:
        msg = getActivity().getString(R.string.error_timeout);
        break;
      case ErrorCode.SSLHandshakeException:
        msg = getActivity().getString(R.string.error_ssl);
        break;
      case ErrorCode.JSON_Exception:
        msg = getActivity().getString(R.string.error_json);
        break;
      default:
        if (TextUtils.isEmpty(msg)) {
          msg = getActivity().getString(R.string.error_unknown_server) + "(" + code + ")";
        }
        break;
    }
    String finalMsg = msg;
    getActivity().runOnUiThread(() -> showToast(finalMsg));

  }

  @Override
  public void showToast(String msg) {
    getActivity().runOnUiThread(() -> super.showToast(msg));
  }

  void updateBroadcastView(@NotNull List broadcastInfo) {
    Intrinsics.checkParameterIsNotNull(broadcastInfo, "broadcastInfo");
    ((BroadcastView) this.get(R.id.bv_main_lunbo)).setbroadcastIndex(1);
    ((BroadcastView) this.get(R.id.bv_main_lunbo)).refreshData(broadcastInfo);
    ((BroadcastView) this.get(R.id.bv_main_lunbo)).startPlay();
  }

  void updateBroadcastView() {
    BroadcastView b = get(R.id.bv_main_lunbo);
    b.setbroadcastIndex(1);
    b.startPlay();
  }

  /**
   * 更新界面Style
   */
  void updateStyle() {
    OwnStyle ownStyle = SPUtils.getInstance(getActivity()).get(ConstantsYJ.OWN_STYLE, OwnStyle.class);
    if (null == ownStyle) {
      return;
    }
    ((SimpleDraweeView) this.get(R.id.head_layout_img)).setImageURI(ownStyle.head_bg);
    ((SimpleDraweeView) this.get(R.id.school_img)).setImageURI(ownStyle.head_url);
    ((SimpleDraweeView) this.get(R.id.code_img)).setImageURI(ownStyle.code_url);
    ((SimpleDraweeView) this.get(R.id.sdv_mid)).setImageURI(ownStyle.mid_bg);
    ((SimpleDraweeView) this.get(R.id.sdv_mid_class)).setImageURI(ownStyle.mid_bg);
    ((SimpleDraweeView) this.get(R.id.sdv_mid_notice)).setImageURI(ownStyle.mid_bg);
    ((SimpleDraweeView) this.get(R.id.sdv_service)).setImageURI(ownStyle.bottom_bg);
    ((SimpleDraweeView) this.get(R.id.sdv_banxun)).setImageURI(ownStyle.bottom_bg);
    ((SimpleDraweeView) this.get(R.id.sdv_notice_img)).setImageURI(ownStyle.bottom_bg);
//    ((SimpleDraweeView) this.get(R.id.mid_layout2_img)).setImageURI(ownStyle.mid_bg);
//    ((SimpleDraweeView) this.get(R.id.mid_layout3_img)).setImageURI(ownStyle.mid_bg);
//    ((SimpleDraweeView) this.get(R.id.mid_layout4_img)).setImageURI(ownStyle.mid_bg);
  }

  public void showNoticeDetailsDialog(Announced announced) {
    Context context = rootView.getContext();
    new AlertDialog.Builder(context)
        .setTitle(!TextUtils.isEmpty(announced.title) ? announced.title : context.getString(R.string.notice_dialog_default_title))
        .setMessage(!TextUtils.isEmpty(announced.value) ? announced.value : context.getString(R.string.notice_dialog_default_value))
        .setPositiveButton(context.getString(R.string.notice_dialog_button), (dialog, which) -> dialog.dismiss())
        .show();
  }

  /**
   * 更新通告
   */
  void updateNotices() {
    List<Announced> announcedList = KJDB.getDefaultInstance().findAll(Announced.class);

    if (null == announcedList || announcedList.size() == 0) {
      get(R.id.tv_empty_notice).setVisibility(View.VISIBLE);
      get(R.id.viewPager).setVisibility(View.GONE);
      return;
    }
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    List<Announced> announcedDataTop = new ArrayList<>();
    List<Announced> announcedData = new ArrayList<>();
    for (int i = 0; i < announcedList.size(); i++) {
      long start_time = 0;
      long end_time = 0;
      try {
        start_time = formatter.parse(announcedList.get(i).start_time).getTime();
        end_time = formatter.parse(announcedList.get(i).end_time).getTime();
      } catch (ParseException e) {
        e.printStackTrace();
      }

      long time = System.currentTimeMillis();

      if (announcedList.get(i).is_top == 1 && time < end_time && time > start_time) {
        Announced announced = new Announced();
        announced.is_top = announcedList.get(i).is_top;
        announced.id = announcedList.get(i).id;
        announced.title = announcedList.get(i).title;
        announced.value = announcedList.get(i).value;
        announced.start_time = announcedList.get(i).start_time;
        announced.end_time = announcedList.get(i).end_time;
        announcedDataTop.add(announced);
      } else if (announcedList.get(i).is_top == 0 && time < end_time && time > start_time) {
        Announced announced = new Announced();
        announced.is_top = announcedList.get(i).is_top;
        announced.id = announcedList.get(i).id;
        announced.title = announcedList.get(i).title;
        announced.value = announcedList.get(i).value;
        announced.start_time = announcedList.get(i).start_time;
        announced.end_time = announcedList.get(i).end_time;
        announcedData.add(announced);
      }
    }

    mNoticesList.clear();
    if (announcedDataTop.size() != 0) {
      mNoticesList.add(announcedDataTop.get(0));
    } else {
      mNoticesList.addAll(announcedData);
    }

    if (mNoticesList == null || mNoticesList.size() == 0) {
      get(R.id.tv_empty_notice).setVisibility(View.VISIBLE);
      get(R.id.viewPager).setVisibility(View.GONE);
    } else {
      get(R.id.tv_empty_notice).setVisibility(View.GONE);
      get(R.id.viewPager).setVisibility(View.VISIBLE);
      mNoticeAdapter.adapterNotifyDataSetChanged(mNoticesList);
    }
//    noticeViewFlipper.removeAllViews();
//    if (null != mNoticesList && mNoticesList.size() > 0) {
//      for (int i = 0; i < mNoticesList.size(); i++) {
//        Announced announced = mNoticesList.get(i);
//        View view = LayoutInflater.from(getActivity()).inflate(R.layout.item_notice_layout, null);
//        TextView textView = view.findViewById(R.id.tv_notice);
//        textView.setText(announced.title );
////        textView.setText(announced.title +": "+ HtmlToStringUtil.replaceBlank(HtmlToStringUtil.getHtmlContent(announced.value)));
//        textView.setSelected(true);
//        textView.setOnClickListener(v -> showNoticeDetailsDialogFragment(announced));
//        noticeViewFlipper.addView(view);
//      }
//      //是否自动开始滚动
//      noticeViewFlipper.setAutoStart(true);
//      //滚动时间
//      noticeViewFlipper.setFlipInterval(20000);
//      //开始滚动
//      noticeViewFlipper.startFlipping();
//      //出入动画
//      noticeViewFlipper.setOutAnimation(getActivity(), R.anim.slider_out_top);
//      noticeViewFlipper.setInAnimation(getActivity(), R.anim.slider_in_bottom);
//    }
  }

  /**
   * 更新密码以及班徽班训
   */
  public void updatePassword() {
    this.mPassword = SPUtils.getInstance(getActivity()).get(ConstantsYJ.SpTag.PASS_WORD, "84159009");
    HomeInfo info = SPUtils.getInstance(rootView.getContext()).get(ConstantsYJ.SpTag.HOME_INFO, HomeInfo.class);
    TextView tvClassName = get(R.id.tv_class_name);
    if (info == null) {
      return;
    }
    if (!TextUtils.isEmpty(info.classname)) {
      tvClassName.setText(info.classname);
    }
    if (!TextUtils.isEmpty(info.classimg)) {
      ((SimpleDraweeView) this.get(R.id.class_img)).setImageURI(info.classimg);
    }
    if (!TextUtils.isEmpty(info.classmotto)) {
      initAnnounced(info.classmotto);
    }

  }

  private long mAnimation = 15000;
  private String mAnnounced = "";
  private String mCountDown = "";

  /**
   * 班训轮播
   *
   * @param msg
   */
  private void initAnnounced(String msg) {
    Slog.i(TAG, "initAnnounced: [msg]" + msg);
    //初始化TextBannerView
    TextBannerView tvBanner = get(R.id.tv_banxun);
    List<String> list = new ArrayList<>();
    int j = msg.length() % 20 == 0 ? msg.length() / 20 - 1 : msg.length() / 20;
    for (int i = 0; i <= j; i++) {
      if (i == j) {
        list.add(msg.substring(i * 20, msg.length()));
      } else {
        list.add(msg.substring(i * 20, i * 20 + 20));
      }
    }
    //调用setDatas(List<String>)方法后,TextBannerView自动开始轮播
    //注意：此方法目前只接受List<String>类型
    tvBanner.setDatas(list);
  }

  void goToNextPager(int position) {
    Slog.i(TAG, "goToNextPager: [position]" + position);
    Slog.i(TAG, "goToNextPager: bannerView.getViewPager().getCurrentItem()" + bannerView.getViewPager().getCurrentItem());
    if (position == bannerView.getViewPager().getCurrentItem()) {
      bannerView.getViewPager().setCurrentItem(bannerView.getViewPager().getCurrentItem() + 1);
    }
  }

  /**
   * 倒计时
   *
   * @param eventName
   */
  private void initCountDownTime(String eventName, long time) {
    if (!TextUtils.isEmpty(eventName + time)) {
      if (!mCountDown.equals(eventName + time)) {
        mCountDown = eventName + time;
        getActivity().runOnUiThread(() -> {
          mAnimation = (eventName + time).length() / 10 * 3000 + 20000;
          if ((eventName + time).length() > 15) {
            startCountdownAnimation();
          } else {
            get(R.id.ll_count_down).clearAnimation();
          }
        });
      }
    } else {
      if (!mCountDown.equals(eventName + time)) {
        mCountDown = eventName + time;
        if (TextUtils.isEmpty(mCountDown)) {
          getActivity().runOnUiThread(() -> {
            get(R.id.ll_count_down).clearAnimation();
          });
        } else {
          getActivity().runOnUiThread(() -> {
            mAnimation = (eventName + time).length() / 50 * 15000 + 20000;
            startCountdownAnimation();
          });
        }
      }
    }
  }

  private TranslateAnimation mRightToLeftAnim;

//  private void startAnimation() {
//    get(R.id.tv_banxun).clearAnimation();
//    get(R.id.tv_banxun).post(() -> {
//      mRightToLeftAnim = new TranslateAnimation(get(R.id.hsv_banxun).getWidth(), -get(R.id.tv_banxun).getWidth(), 0, 0);
//      mRightToLeftAnim.setRepeatCount(Animation.INFINITE);
//      mRightToLeftAnim.setInterpolator(new LinearInterpolator());
//      mRightToLeftAnim.setDuration(mAnimation);
//      get(R.id.tv_banxun).startAnimation(mRightToLeftAnim);
//    });
//  }

  private void startCountdownAnimation() {
    get(R.id.ll_count_down).clearAnimation();
    get(R.id.ll_count_down).post(() -> {
      mRightToLeftAnim = new TranslateAnimation(get(R.id.hsv_count_down).getWidth(), -get(R.id.ll_count_down).getWidth(), 0, 0);
      mRightToLeftAnim.setRepeatCount(Animation.INFINITE);
      mRightToLeftAnim.setInterpolator(new LinearInterpolator());
      mRightToLeftAnim.setDuration(mAnimation);
      get(R.id.ll_count_down).startAnimation(mRightToLeftAnim);
    });
  }

  /**
   * 更新天气
   */
  @SuppressLint("SetTextI18n")
  void updateWeather(Context context, Weather weather) {
    TextView tvTemperature = get(R.id.tv_temperature);
    TextView tvWeather = get(R.id.tv_weather);
    GifImageView imgWeather = get(R.id.img_weather);
    Weather.AreaToWeather.Body body = weather.area_to_weather.showapi_res_body;
    tvTemperature.setText(body.f1.day_air_temperature + context.getResources().getString(R.string.max_oc));
    tvWeather.setText(body.f1.day_weather);
    if (WeatherUtil.map.containsKey(body.f1.day_weather)) {
      imgWeather.setImageResource(WeatherUtil.get(body.f1.day_weather));
    }
  }

  /**
   * 小应用
   */
  void updateApps() {
    try {
      AppInfoRspS appInfoRsp = SPUtils.getInstance(getActivity()).get(ConstantsYJ.SpTag.APP_INFO, AppInfoRspS.class);
      if (null == appInfoRsp) {
        return;
      }
      List<AppInfoRspS.Apps> apps = appInfoRsp.extra;
      this.mAppsInfo.clear();
      if (null != apps && apps.size() > 0) {
        this.mAppsInfo.addAll(apps);
      }
//      sort_list.start();
      itemSortAdapter.adapterNotifyDataSetChanged(mAppsInfo);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * 二维码
   */
  void updateQrCode() {
    Slog.d(TAG, "start updateQrCode");
    getActivity().runOnUiThread(() -> {
      ImageView imgQrCode = get(R.id.iv_qr_code);
      if (!((MainActivity) getActivity()).isNetConnected()) {
        // 断网屏蔽扫码功能
        Slog.d(TAG, "updateQrCode abort: network disconnected!");
        imgQrCode.setImageResource(R.mipmap.load_fail_qr_code);
        return;
      }
      if (!AppConfig.isCode(getActivity())) {
        // 不支持扫码功能
        Slog.d(TAG, "updateQrCode abort: nonsupport code!");
        imgQrCode.setImageResource(R.mipmap.load_fail_qr_code);
        return;
      }
      List<QrCode> qrCodeList = KJDB.getDefaultInstance().findAll(QrCode.class);
      if (qrCodeList != null && !qrCodeList.isEmpty()) {
        QrCode qrCode = qrCodeList.get(0);
        if (qrCode != null) {
          String url = qrCode.url;
          if (!TextUtils.isEmpty(url)) {
            Bitmap bitmap = QrCodeUtil.createQRCodeBitmap(
                url
                    + "?device_id=" + toURLEncoded(ConfigDevice.getDeviceId())
                    + "&school_id=" + ConfigDevice.school_id,
                400,
                400
            );
            imgQrCode.setImageBitmap(bitmap);
            return;
          }
        }
      }
      imgQrCode.setImageResource(R.mipmap.load_fail_qr_code);
    });
  }

  private Subscription mCameraTimerSubscription;

  /**
   * 定时更新相机开关状态
   */
  private void regularlySetCameraStatus() {
    Slog.d(TAG, "start regularlySetCameraStatus");
    updateCameraStatusBySignTime();
    updateQrCode();

    if (mCameraTimerSubscription != null && !mCameraTimerSubscription.isUnsubscribed()) {
      mCameraTimerSubscription.unsubscribe();
    }
    mCameraTimerSubscription = Observable.timer(20, TimeUnit.SECONDS).subscribe(r ->
        regularlySetCameraStatus());
    ((ActivityBase) getActivity()).addRxSubscription(mCameraTimerSubscription);
  }

  /**
   * 签到时间内 && 已经配置硬件信息：开启相机； 否则关闭相机
   */
  void updateCameraStatusBySignTime() {
    Slog.d(TAG, "start updateCameraStatusBySignTime");
    if (!AppConfig.isFace(getActivity())) {
      // 不支持人脸识别
      Slog.d(TAG, "updateCameraStatusBySignTime abort: nonsupport face!");
      stopCamera();
      return;
    }
    DeviceInfo deviceInfo = SPUtils.getInstance(getActivity()).get(ConstantsYJ.SpTag.DEVICE_INFO, DeviceInfo.class);
    if (deviceInfo == null || deviceInfo.cameras == null || deviceInfo.cameras.isEmpty()) {
      // 没有配置硬件信息
      Slog.d(TAG, "updateCameraStatusBySignTime abort: no deviceInfo!");
      stopCamera();
      return;
    }
    // 默认打开id为0的摄像头，如果打开失败，则继续尝试打开后面的
    for (DeviceInfo.Camera camera : deviceInfo.cameras) {
      if (camera != null && openCamera(camera.position, getCameraDegree(camera.orientation))) {
        return;
      }
    }
  }

  /**
   * 获取摄像机预览角度
   */
  private int getCameraDegree(int orientation) {
    switch (orientation) {
      case 1:
        return 0;
      case 2:
        return 90;
      case 3:
        return 180;
      default:
        return 270;
    }
  }

  private String toURLEncoded(String paramString) {
    if (TextUtils.isDigitsOnly(paramString)) {
      return "";
    }
    try {
      String str = new String(paramString.getBytes(), "UTF-8");
      str = URLEncoder.encode(str, "UTF-8");
      return str;
    } catch (Exception localException) {
      Slog.e(TAG + " toURLEncoded error:" + paramString, localException.getMessage());
    }
    return "";
  }

  private NoticeDialogFragment noticeDialogFragment;
  private Subscription noticeSubscription;
  private ParentStudentDialogFragment parentStudentDialogFragment;
  private Subscription parentStudentSubscription;
  private StudentDialogFragment studentDialogFragment;
  private Subscription studentSubscription;
  //  private ConfirmStudentDialogFragment confirmStudentDialogFragment;
//  private Subscription confirmStudentSubscription;
  private SignSearchDialogFragment allSignRecordDialogFragment;

  /**
   * 通告弹框
   *
   * @param announced
   */
  public void showNoticeDetailsDialogFragment(Announced announced) {
    if (null != noticeDialogFragment) {
      noticeDialogFragment.dismiss();
    }
    noticeDialogFragment = new NoticeDialogFragment();
    noticeDialogFragment.setOnDialogKeyListener(new OnDialogKeyListener() {
      @Override
      public void onKeyDown(int keyCode, @NonNull KeyEvent event) {
        (getActivity()).onKeyDown(keyCode, event);
      }

      @Override
      public void onKeyUp(int keyCode, @NonNull KeyEvent event) {
        (getActivity()).onKeyUp(keyCode, event);
      }
    });
    noticeDialogFragment.setDialogContent(announced);
    noticeDialogFragment.show(getActivity().getFragmentManager(), "noticeDialogFragment");
    if (null != noticeSubscription && !noticeSubscription.isUnsubscribed()) {
      noticeSubscription.unsubscribe();
    }
    noticeSubscription = Observable.timer(120, TimeUnit.SECONDS)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(r ->
            noticeDialogFragment.dismiss());
    ((ActivityBase) getActivity()).addRxSubscription(noticeSubscription);
  }

  /**
   * 学生家长信息框
   *
   * @param student
   */
  public void showParentStudentInfo(Student student) {
    if (AppConfig.isShowPhoto(getActivity())) {
      showStudentDialogFragment(student);
    }
  }

  /**
   * 学生家长信息框
   *
   * @param student
   */
  public void showParentStudentDialogFragment(Student student) {
    if (null != parentStudentDialogFragment) {
      parentStudentDialogFragment.dismiss();
    }
    parentStudentDialogFragment = new ParentStudentDialogFragment();
    parentStudentDialogFragment.setOnDialogKeyListener(new OnDialogKeyListener() {
      @Override
      public void onKeyDown(int keyCode, @NonNull KeyEvent event) {
        (getActivity()).onKeyDown(keyCode, event);
      }

      @Override
      public void onKeyUp(int keyCode, @NonNull KeyEvent event) {
        (getActivity()).onKeyUp(keyCode, event);
      }
    });
    parentStudentDialogFragment.setDialogContent(student);
    parentStudentDialogFragment.show(getActivity().getFragmentManager(), "");
    if (null != parentStudentSubscription && !parentStudentSubscription.isUnsubscribed()) {
      parentStudentSubscription.unsubscribe();
    }
    parentStudentSubscription = Observable.timer(AppConfig.TIME_SYNC_STUDENT_DIALOG_DELAY_MS, TimeUnit.SECONDS)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(r ->
            parentStudentDialogFragment.dismiss());
    ((ActivityBase) getActivity()).addRxSubscription(parentStudentSubscription);
  }

  /**
   * 学生信息框
   *
   * @param student
   */
  public void showStudentDialogFragment(Student student) {
    if (null != studentDialogFragment) {
      studentDialogFragment.dismiss();
    }
    studentDialogFragment = new StudentDialogFragment();
    studentDialogFragment.setOnDialogKeyListener(new OnDialogKeyListener() {
      @Override
      public void onKeyDown(int keyCode, @NonNull KeyEvent event) {
        (getActivity()).onKeyDown(keyCode, event);
      }

      @Override
      public void onKeyUp(int keyCode, @NonNull KeyEvent event) {
        (getActivity()).onKeyUp(keyCode, event);
      }
    });
    studentDialogFragment.setDialogContent(student);
    studentDialogFragment.show(getActivity().getFragmentManager(), "");
    if (null != studentSubscription && !studentSubscription.isUnsubscribed()) {
      studentSubscription.unsubscribe();
    }
    studentSubscription = Observable.timer(AppConfig.TIME_SYNC_STUDENT_DIALOG_DELAY_MS, TimeUnit.SECONDS)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(r ->
            studentDialogFragment.dismiss());
    ((ActivityBase) getActivity()).addRxSubscription(studentSubscription);
  }

  /**
   * 选择学生信息框 弹框不做覆盖操作
   *
   * @param responseS
   * @param mCurrentPhone
   * @param mCurrentTime
   * @param swipeStatus
   * @param onSelectStudentDialogListener
   */
  public void showSelectStudentDialogFragment(ParentLinkStudentsResponseS responseS, String mCurrentPhone, long mCurrentTime,
                                              int swipeStatus, OnSelectStudentDialogListener onSelectStudentDialogListener) {
    SelectStudentDialogFragment selectStudentDialogFragment = new SelectStudentDialogFragment();
    selectStudentDialogFragment.setOnDialogKeyListener(new OnDialogKeyListener() {
      @Override
      public void onKeyDown(int keyCode, @NonNull KeyEvent event) {
        (getActivity()).onKeyDown(keyCode, event);
      }

      @Override
      public void onKeyUp(int keyCode, @NonNull KeyEvent event) {
        (getActivity()).onKeyUp(keyCode, event);
      }
    });
    Subscription selectStudentSubscription = Observable.timer(AppConfig.TIME_SYNC_SELECT_STUDENT_DIALOG_DELAY_MS, TimeUnit.SECONDS)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(aLong -> {
          selectStudentDialogFragment.dismiss();
          if (null != selectStudentDialogFragment.getItemStudentAdapter() && null != onSelectStudentDialogListener) {
            ParentLinkStudentsResponseS responseS1 = new ParentLinkStudentsResponseS();
            responseS1.students = selectStudentDialogFragment.getItemStudentAdapter().getStudents();
            onSelectStudentDialogListener.setOnSelectStudentDialogListener(responseS1, mCurrentPhone, mCurrentTime, swipeStatus);
          }
        });
    ((ActivityBase) getActivity()).addRxSubscription(selectStudentSubscription);
    selectStudentDialogFragment.setDialogContent(responseS, students -> {
      if (null != selectStudentSubscription && !selectStudentSubscription.isUnsubscribed()) {
        selectStudentSubscription.unsubscribe();
      }
      ParentLinkStudentsResponseS responseS1 = new ParentLinkStudentsResponseS();
      responseS1.students = students;
      responseS1.pick_up_status = responseS.pick_up_status;
      if (null != onSelectStudentDialogListener) {
        onSelectStudentDialogListener.setOnSelectStudentDialogListener(responseS1, mCurrentPhone, mCurrentTime, swipeStatus);
      }
    });
    selectStudentDialogFragment.show(getActivity().getFragmentManager(), "");
  }

//  /**
//   * 确认学生信息框
//   *
//   * @param responseS
//   */
//  public void showConfirmStudentDialogFragment(ParentLinkStudentsResponseS responseS, String mCurrentPhone, long mCurrentTime,
//                                               int swipeStatus, OnSelectStudentDialogListener onSelectStudentDialogListener) {
//    if (null != confirmStudentDialogFragment) {
//      confirmStudentDialogFragment.dismiss();
//    }
//    confirmStudentDialogFragment = new ConfirmStudentDialogFragment();
//    confirmStudentDialogFragment.setOnDialogKeyListener(new OnDialogKeyListener() {
//      @Override
//      public void onKeyDown(int keyCode, @NonNull KeyEvent event) {
//        (getActivity()).onKeyDown(keyCode, event);
//      }
//
//      @Override
//      public void onKeyUp(int keyCode, @NonNull KeyEvent event) {
//        (getActivity()).onKeyUp(keyCode, event);
//      }
//    });
//    confirmStudentDialogFragment.setDialogContent(responseS, responseS1 -> {
//      if (null != onSelectStudentDialogListener) {
//        onSelectStudentDialogListener.setOnSelectStudentDialogListener(responseS1, mCurrentPhone, mCurrentTime, swipeStatus);
//      }
//    });
//    confirmStudentDialogFragment.show(getActivity().getFragmentManager(), "");
//
//    if (null != confirmStudentSubscription && !confirmStudentSubscription.isUnsubscribed()) {
//      confirmStudentSubscription.unsubscribe();
//    }
//    confirmStudentSubscription = Observable.timer(AppConfig.TIME_SYNC_SELECT_STUDENT_DIALOG_DELAY_MS, TimeUnit.SECONDS).subscribe(r ->
//            confirmStudentDialogFragment.dismiss());
//    ((ActivityBase) getActivity()).addRxSubscription(confirmStudentSubscription);
//  }

  /**
   * 学生所有签到记录信息框
   */
  public void showAllSignRecordDialogFragment() {
    if (null != allSignRecordDialogFragment) {
      allSignRecordDialogFragment.dismiss();
    }
    allSignRecordDialogFragment = new SignSearchDialogFragment();
    allSignRecordDialogFragment.setOnDialogKeyListener(new OnDialogKeyListener() {
      @Override
      public void onKeyDown(int keyCode, @NonNull KeyEvent event) {
        (getActivity()).onKeyDown(keyCode, event);
      }

      @Override
      public void onKeyUp(int keyCode, @NonNull KeyEvent event) {
        (getActivity()).onKeyUp(keyCode, event);
      }
    });
    allSignRecordDialogFragment.show(getActivity().getFragmentManager(), "noticeDialogFragment");
  }

  @Override
  protected void activityResume(boolean resume) {
    super.activityResume(resume);
    BroadcastView b = get(R.id.bv_main_lunbo);
    if (b != null) {
      b.activityResume(resume);
    }
  }

  private Subscription mUserInfoTimerSubscription;

  /**
   * 刷卡、扫码、人脸识别成功或失败时的界面显示
   *
   * @param statusText      如：刷卡成功
   * @param statusTextColor 消费状态的字体颜色
   * @param students        学生信息
   */
  void setUserInfoTextOnLine(String statusText, int statusTextColor, List<Student> students) {
    setUserInfoTextOnLine(statusText, statusTextColor, students, AppConfig.TIME_SYNC_STUDENT_DIALOG_DELAY_MS);
  }

  /**
   * 刷卡、扫码、人脸识别成功或失败时的界面显示
   *
   * @param statusText      如：刷卡成功
   * @param statusTextColor 消费状态的字体颜色
   * @param students        学生信息
   * @param duration        该状态的持续时间，到时会自动清空
   */
  void setUserInfoTextOnLine(String statusText, int statusTextColor, List<Student> students, int duration) {

    if (mUserInfoTimerSubscription != null && !mUserInfoTimerSubscription.isUnsubscribed()) {
      mUserInfoTimerSubscription.unsubscribe();
    }
    mUserInfoTimerSubscription = Observable.timer(duration, TimeUnit.SECONDS).subscribe(aLong ->
        ((Activity) rootView.getContext()).runOnUiThread(this::clearStatusText));
    ((ActivityBase) rootView.getContext()).addRxSubscription(mUserInfoTimerSubscription);
    clearStatusText();
    ((TextView) get(R.id.tv_swipe_status)).setText(TextUtils.isEmpty(statusText) ? "" : statusText);
    ((TextView) get(R.id.tv_swipe_status)).setTextColor(statusTextColor);
    if (null != students && students.size() > 0) {
      StringBuilder cardNoSb = new StringBuilder();
      StringBuilder unionIdSb = new StringBuilder();
      StringBuilder nameSb = new StringBuilder();
      for (int i = 0; i < students.size(); i++) {
        Student student = students.get(i);
        if (i == students.size() - 1) {
          cardNoSb.append(TextUtils.isEmpty(student.card_no) ? "" : student.card_no);
          unionIdSb.append(TextUtils.isEmpty(student.union_id) ? "" : student.union_id);
          nameSb.append(TextUtils.isEmpty(student.name) ? "" : student.name);
        } else {
          cardNoSb.append(TextUtils.isEmpty(student.card_no) ? "" : (student.card_no + "、"));
          unionIdSb.append(TextUtils.isEmpty(student.union_id) ? "" : (student.union_id + "、"));
          nameSb.append(TextUtils.isEmpty(student.name) ? "" : (student.name + "、"));
        }
      }
      ((TextView) get(R.id.tv_card_no)).setText(cardNoSb.toString());
      ((TextView) get(R.id.tv_union_id)).setText(unionIdSb.toString());
      ((TextView) get(R.id.tv_username)).setText(nameSb.toString());
    }
  }

  private void clearStatusText() {
    ((TextView) get(R.id.tv_swipe_status)).setText("");
    ((TextView) get(R.id.tv_card_no)).setText("");
    ((TextView) get(R.id.tv_union_id)).setText("");
    ((TextView) get(R.id.tv_username)).setText("");
  }


  // 以下是人脸识别相关//////////////////////////////////////////////////////////////////////////////

  /**
   * 预览宽度
   */
  private int mPreviewWidth;
  /**
   * 预览高度
   */
  private int mPreviewHeight;
  private DetectPresenter mPresenter;
  private long mLastDebugText = 0;

  private ArrayList<Float> features = new ArrayList<>();

  void initCameraData() {
    mPresenter = new DetectPresenter(this);
    CameraInterfaceBak.getInstance().setCameraStateCallBack(this);
  }

  @SuppressLint("SetTextI18n")
  @Override
  public void recognizeFace(UserBean userBean) {
    Slog.d(TAG_DEBUG_FACE, "recognizeFace userId:" + userBean.userId + userBean.name + "\nimageUrl:" + userBean.urlImagePath);
    getActivity().runOnUiThread(() -> {
      synchronized (userBean) {
        //通知关闭全屏广播界面
        RxBus.get().post(ConstantsYJ.RxTag.RX_TAG_CONFIRM_USER, userBean.userId);
        ((TextView) get(R.id.tv_debug_msg)).setText(
            getActivity().getString(R.string.success_recognized) + ":" + userBean.name);
      }
    });
  }

  @Override
  public void recognizeFaceNotMatch(UserBean userBean) {
    if (features.size() > 0) {
      Slog.d(TAG_DEBUG_FACE, "extractFeatureASync find recognizeFaceNotMatch");
      ArrayList<Float> floatArrayList = new ArrayList<>();
      floatArrayList.clear();
      floatArrayList.addAll(features);
      final float compare = FaceDetectManager.compareFeature(FeatureUtils.arrayListToFloat(floatArrayList), FeatureUtils.arrayListToFloat(userBean.features));
      LogUtils.d(TAG_DEBUG_FACE, "extractFeatureASync find recognizeFaceNotMatch : " + compare);
      if (compare > ConfigLib.featureThreshold) {
        // 识别成功
        Message message = Message.obtain();
        message.obj = userBean.headImage;
        features.clear();
        showSlotCardState(getActivity().getResources().getString(R.string.match_success) + " : " + compare);
      } else {
        showSlotCardState(getActivity().getResources().getString(R.string.match_fail) + " : " + compare);
      }
    }
  }

  private void showSlotCardState(final String state) {
    getActivity().runOnUiThread(() -> ((TextView) get(R.id.tv_debug_msg)).setText(state));
  }

  @Override
  public void detectNoFace() {
    Slog.d(TAG_DEBUG_FACE, "detectFace: detectNoFace");
    getActivity().runOnUiThread(() -> {
      mLastDebugText = System.currentTimeMillis();
      ((TextView) get(R.id.tv_debug_msg)).setText(getActivity().getString(R.string.no_face));
      ((TextView) get(R.id.tv_camera_debug_message)).setText("");
      updatePreviewMessage("");
    });
  }

  @Override
  public void detectFail(Status status) {
    Slog.d(TAG_DEBUG_FACE, "detectFace: detectFail");
    getActivity().runOnUiThread(() -> {
      ((TextView) get(R.id.tv_debug_msg)).setText(getActivity().getString(R.string.detect_face));
      updatePreviewMessage(status.toString());
    });
  }

  private void updatePreviewMessage(String s) {
    String stringBuilder = ("w = " + mPreviewWidth + " h = " + mPreviewHeight) + s;
    ((TextView) get(R.id.tv_camera_message)).setText(stringBuilder);
  }

  @Override
  public void detectFace(List<FaceBean> faceBeans) {
    Slog.d(TAG_DEBUG_FACE, "detectFace: detectFace");
    getActivity().runOnUiThread(() -> {
      synchronized (faceBeans) {
        List<FaceBean> faceBeanList = new ArrayList<>();
        faceBeanList.clear();
        faceBeanList.addAll(faceBeans);
        StringBuilder stringBuilder = new StringBuilder();
        try {
          for (int i = 0; i < faceBeanList.size(); i++) {
            FaceBean bean = faceBeanList.get(i);
            if (bean.mUserBean != null && !StringUtils.isEmpty(bean.mUserBean.name)) {
              // 显示人名
              String name = bean.mUserBean.name;
              stringBuilder.append("Find name:").append(name).append("");
            }
            String score = "";
            if (ConfigLib.detectWithLiveness || ConfigLib.detectWithInfraredLiveness) {
              // 显示活体识别分数
              if (bean.mLiveBean != null && bean.mLiveBean.livenessTag == bean.mLiveBean.UNKNOWN) {
                score = getActivity().getString(R.string.unknown_status);
              } else if (bean.mLiveBean != null && bean.mLiveBean.livenessTag == bean.mLiveBean.FAKE) {
                score = getActivity().getString(R.string.unknown_status);
              } else {
                if (bean.mUserBean != null) {
                  score = new DecimalFormat(".00").format(bean.mUserBean.compareScore);
                }
              }
            } else {// 显示非活体识别分数
              if (bean.mUserBean != null) {
                score = bean.mUserBean.compareScore + "";
              }
            }
            stringBuilder.append(" score:").append(score).append("");
          }
        } catch (Exception e) {
          e.printStackTrace();
        }

        ((TextView) get(R.id.tv_debug_msg)).setText(stringBuilder.toString());
        if (System.currentTimeMillis() - mLastDebugText > 1000) {
          ((TextView) get(R.id.tv_camera_debug_message)).setText("");
        }
      }
    });
  }

  @Override
  public void debug(FaceBean faceBean) {

  }

  private boolean openCamera(final int id, final int degree) {
    Slog.d(TAG_DEBUG_FACE, "start openCamera id:" + id + ",degree:" + degree);
    if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
        != PackageManager.PERMISSION_GRANTED) {
      Slog.d(TAG_DEBUG_FACE, "openCamera abort: permission not granted!");
      return false;
    }
    if (mCameraIsOpened) {
      // 相机已打开
      Slog.d(TAG_DEBUG_FACE, "openCamera abort: mCameraIsOpened!");
      return false;
    }
    if (!AttConstants.INIT_STATE) {
      // 人脸sdk未初始化
      Slog.d(TAG_DEBUG_FACE, "openCamera abort: sdk not init!");
      //适配非触摸版班牌
//      if (Camera.getNumberOfCameras() != 0) {
//        getActivity().runOnUiThread(()
//                -> showToast(getActivity().getString(R.string.being_init_face_sdk)));
//      MyApp.initAiwinnFace(null);
//      }
      return false;
    }
    int supportedMaxId = Camera.getNumberOfCameras();
    if (id < 0 || id >= supportedMaxId) {
      // 拦截设备不支持的CameraId
      Slog.d(TAG_DEBUG_FACE, "openCamera abort:" + getActivity().getString(R.string.fail_open_unsupported_camera_id)
          + id + "(supported" + (supportedMaxId - 1) + ")");
      getActivity().runOnUiThread(() ->
          showToast(getActivity().getString(R.string.fail_open_unsupported_camera_id)
              + id + "(supported" + (supportedMaxId - 1) + ")"));
      return false;
    }
    AttConstants.Detect_Exception = true;
    getActivity().runOnUiThread(() -> {
      get(R.id.sv_camera).setVisibility(View.VISIBLE);
      get(R.id.tv_camera_message).setVisibility(View.VISIBLE);
      get(R.id.tv_camera_debug_message).setVisibility(View.VISIBLE);
      get(R.id.tv_debug_msg).setVisibility(View.VISIBLE);
      get(R.id.iv_avatar).setVisibility(View.GONE);
    });
    CameraInterfaceBak.getInstance().setPreViewSize(AttConstants.CAMERA_PREVIEW_WIDTH, AttConstants.CAMERA_PREVIEW_HEIGHT);

    Thread openThread = new Thread() {
      @Override
      public void run() {
        try {
          Thread.sleep(100);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        if (AttConstants.INIT_STATE) {
          // 如果没有初始化，此处setDegree会报异常
          FaceDetectManager.setDegree(degree);
          CameraInterfaceBak.getInstance().doOpenCamera(id, degree);
        }
      }
    };
    openThread.start();
    mCameraIsOpened = true;
    Slog.d(TAG_DEBUG_FACE, "openCamera success [id]:" + id + ",[degree]:" + degree);
    return true;
  }

  private boolean mCameraIsOpened = false;

  @Override
  public void cameraHasOpened() {
    Slog.d(TAG_DEBUG_FACE, "cameraHasOpened");
    Camera camera = CameraInterfaceBak.getInstance().mCamera;
    if (camera == null) {
      Slog.e(TAG_DEBUG_FACE, "cameraHasOpened error: camera is null!");
      return;
    }
    camera.setErrorCallback(mCameraErrorCallback);
    CameraSurfaceView svCamera = get(R.id.sv_camera);
    while (true) {
      if (!svCamera.hasCreated) {
//        Slog.d(TAG_DEBUG_FACE, "wait CameraSurfaceView created !");
        try {
          Thread.sleep(50);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      } else {
        break;
      }
    }
    Slog.d(TAG_DEBUG_FACE, "openCamera mCameraHasError:" + mCameraHasError);
    if (mCameraHasError) {
      mCameraHasError = false;
      return;
    }
    CameraInterfaceBak.getInstance().doStartPreview(svCamera.getSurfaceHolder());
  }

  private boolean mCameraHasError = false;

  private Camera.ErrorCallback mCameraErrorCallback = (error, camera) -> {
    Slog.d(TAG_DEBUG_FACE, "openCamera ErrorCallback:" + error);
    switch (error) {
      case Camera.CAMERA_ERROR_SERVER_DIED:
      case Camera.CAMERA_ERROR_UNKNOWN:
        Slog.e(TAG_DEBUG_FACE, "openCamera ErrorCallback:" + error);
//        mCameraHasError = true;
        stopCamera();
        //这里重新初始化Camera即可
        updateCameraStatusBySignTime();
        break;
    }
  };

  @Override
  public void cameraHasParameters() {
    mPreviewWidth = CameraInterfaceBak.getInstance().getPreviewWidth();
    mPreviewHeight = CameraInterfaceBak.getInstance().getPreviewHeight();
  }

  @Override
  public void cameraHasPreview(byte[] data, Camera camera) {
    this.data = data;
    if (controlFrame()) {
      Slog.d(TAG, "Begin -> ( w = " + mPreviewWidth + " h = " + mPreviewHeight + " size = " + data.length + " )");
      mPresenter.detectFaceData(data, mPreviewWidth, mPreviewHeight);
    }
  }

  private byte[] data;

  public Bitmap getFaceBitmap() {
    if (null == data) {
      return null;
    }
    return Utils.getBitmap(data, mPreviewWidth, mPreviewHeight);
  }

  private int nowFrame = 1;

  /**
   * 控制一定帧数才检测一次人脸
   */
  private boolean controlFrame() {
    Slog.d(TAG, "start controlFrame, nowFrame: " + nowFrame);
    nowFrame++;
    dismissProgress();
    if (nowFrame >= 8) {
      nowFrame = 1;
      return true;
    } else {
      return false;
    }
  }

  @Override
  public void onAStart() {
    super.onAStart();
    regularlySetCameraStatus();
  }

  @Override
  public void onASTop() {
    stopCamera();
    if (mCameraTimerSubscription != null && !mCameraTimerSubscription.isUnsubscribed()) {
      mCameraTimerSubscription.unsubscribe();
    }
    super.onASTop();
  }

  @Override
  public void onADestory() {
    super.onADestory();
    BroadcastView b = get(R.id.bv_main_lunbo);
    if (b != null) {
      b.destory();
    }
  }

  private void stopCamera() {
    AttConstants.Detect_Exception = false;
    mCameraIsOpened = false;
    getActivity().runOnUiThread(() -> {
      get(R.id.sv_camera).setVisibility(View.GONE);
      get(R.id.tv_camera_message).setVisibility(View.GONE);
      get(R.id.tv_camera_debug_message).setVisibility(View.GONE);
      get(R.id.tv_debug_msg).setVisibility(View.GONE);
      get(R.id.iv_avatar).setVisibility(View.VISIBLE);
      CameraInterfaceBak.getInstance().doStopCamera();
    });
  }

  /**
   * 展示天气popwindow
   */
  void showWeatherPopwindow(Context context, Weather weatherResponse) {
    WeatherPopwindow weatherPopwindow = new WeatherPopwindow(context);
    weatherPopwindow.initCalendar(weatherResponse);
    get(R.id.ll_weather).setOnClickListener(new OnClickEffectiveListener() {
      @Override
      public void onClickEffective(View v) {
        weatherPopwindow.showWeather(get(R.id.ll_weather));
      }
    });
  }

  public LinearLayout getCountTimeLL() {
    return get(R.id.ll_count_down);
  }

  public void updateCountTime(CountDownTimeInfoResponse.CountdownTime extra) {
    TextView tvEventName = get(R.id.tv_event_name);
    if (!TextUtils.isEmpty(extra.eventName)) {
      tvEventName.setText(extra.eventName);
    }
    //1为倒计时d
    if (extra.type == 1) {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      Date date = new Date(extra.targetTime * 1000);
      Date today = null;
      Date target = null;
      try {
        target = sdf.parse(sdf.format(date));
        today = sdf.parse(sdf.format(new Date()));
        long targetT = target.getTime();
        long todayTime = today.getTime();
        long currentTime = todayTime / 1000;
        long targetTime = targetT / 1000;
        //86400 = 60 * 60 * 24
        long countTime = (targetTime - currentTime) % 86400 == 0 ? (targetTime - currentTime) / 86400 : ((targetTime - currentTime) / 86400) + 1;
        if (targetTime - currentTime > 0 && !Utils.isToday(targetTime)) {
          TextView tvCountTime = get(R.id.tv_count_time);
          tvCountTime.setText(countTime + "");
          get(R.id.ll_count_down).setVisibility(View.VISIBLE);

          initCountDownTime(extra.eventName, countTime);
        } else {
          get(R.id.ll_count_down).setVisibility(View.GONE);
        }
      } catch (ParseException e) {
        e.printStackTrace();
      }

    }

    //正计时
//    else {
//      long currentTime = System.currentTimeMillis() / 1000;
//      long countTime = (currentTime - extra.targetTime) % 86400 == 0 ? (currentTime - extra.targetTime) / 86400 : ((currentTime - extra.targetTime) / 86400) + 1;
//      if (currentTime - extra.targetTime > 0 && !Utils.isToday(extra.targetTime)) {
//        tvCountTime.setText(countTime + "");
//        get(R.id.ll_count_down).setVisibility(View.VISIBLE);
//      } else {
//        get(R.id.ll_count_down).setVisibility(View.GONE);
//      }
//    }

  }

  public void updateRedFlag() {
    if (SPUtils.getInstance(rootView.getContext()).get(ConstantsYJ.RED_FLAG_INFO, 0) == 1) {
      get(R.id.sdv_flag).setVisibility(View.VISIBLE);
    } else {
      get(R.id.sdv_flag).setVisibility(View.GONE);
    }
  }

  //更新校训显示
    public void updateXiaoXun() {
      MottoItem ownStyle = SPUtils.getInstance(getActivity()).get(ConstantsYJ.XIAOXUN_STYLE, MottoItem.class);
      if (ownStyle != null) {
        ((SimpleDraweeView) this.get(R.id.sdv_mid_xiaoxun)).setImageURI(ownStyle.image_url);
      } else {
        this.get(R.id.sdv_mid_xiaoxun).setVisibility(View.GONE);
        this.get(R.id.iv_noxiaoxun).setVisibility(View.VISIBLE);
      }
    }

  public void updateIOTConfig() {
    String iot_config = SPUtils.getInstance(getActivity()).get(ConstantsYJ.IOT_CONFIG, "");
    Slog.d(TAG, "updateIOTConfig: " + iot_config);

    IOTConfigBean iotConfigBean = new Gson().fromJson(iot_config, IOTConfigBean.class);
    String user = iotConfigBean.getDevice_info().getAlarm_user();
    String password = iotConfigBean.getDevice_info().getAlarm_password();
    String ip = iotConfigBean.getDevice_info().getAlarm_ip();
    String other_user = iotConfigBean.getDevice_info().getAlarm_other_user();

    if (!TextUtils.isEmpty(user) && !TextUtils.isEmpty(password) && !TextUtils.isEmpty(ip) && !TextUtils.isEmpty(other_user)) {
      Intent config = new Intent("org.sipdroid.sipua.config");
      config.putExtra("config", "{\"username\":\"" + user + "\",\"password\":\"" + password + "\",\"service\":\"" + ip + "\"}");
      getActivity().sendBroadcast(config);

      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }

      Intent stop = new Intent("org.sipdroid.sipua.stop_service");
      getActivity().sendBroadcast(stop);

      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }

      Intent intent = new Intent();
      intent.setComponent(new ComponentName("org.sipdroid.sipua", "org.sipdroid.sipua.ui.MyService"));
      getActivity().startService(intent);
    }
  }

//  void showCalendarPopwindow(Context context) {
//    //初始化日历popwindow
//    CalendarPopwindow calendarPopwindow = new CalendarPopwindow(context);
//    calendarPopwindow.initCalendar();
//    get(R.id.cl_calendar).setOnClickListener(new OnClickEffectiveListener() {
//      @Override
//      public void onClickEffective(View v) {
//        calendarPopwindow.showCalendar(get(R.id.cl_calendar));
//      }
//    });
//  }

  private class MyWebChromeClient extends WebChromeClient {
    @Override
    public void onReceivedTitle(WebView view, String title) {
      super.onReceivedTitle(view, title);
    }
  }

  /**
   * 设置展示的模块
   *
   * @param rsp
   */
  public void updateUI(DeviceInfoRsp rsp) {
    // 消费模式支持：刷卡、刷脸、扫二维码
    if (rsp.extra.verification_mode != null && !rsp.extra.verification_mode.isEmpty()) {
      get(R.id.ll_face).setVisibility(View.GONE);
      get(R.id.ll_qr_code).setVisibility(View.GONE);
      if (rsp.extra.verification_mode.size() <= 1) {
        if ("1".equals(rsp.extra.verification_mode.get(0))) {
          AppConfig.setNfc(1, rootView.getContext());
          get(R.id.ll_qr_code).setVisibility(View.GONE);
          AppConfig.setCode(0, rootView.getContext());
          get(R.id.ll_face).setVisibility(View.GONE);
          AppConfig.setFace(0, rootView.getContext());
        }
        if ("2".equals(rsp.extra.verification_mode.get(0))) {
          AppConfig.setFace(1, rootView.getContext());
          get(R.id.ll_face).setVisibility(View.VISIBLE);
          get(R.id.ll_qr_code).setVisibility(View.GONE);
          AppConfig.setCode(0, rootView.getContext());
          AppConfig.setNfc(0, rootView.getContext());
        }

        if ("3".equals(rsp.extra.verification_mode.get(0))) {
          get(R.id.ll_qr_code).setVisibility(View.VISIBLE);
          AppConfig.setCode(1, rootView.getContext());
          get(R.id.ll_face).setVisibility(View.GONE);
          AppConfig.setFace(0, rootView.getContext());
          AppConfig.setNfc(0, rootView.getContext());
        }
      } else {
        for (int i = 0; i < rsp.extra.verification_mode.size(); i++) {
          if ("1".equals(rsp.extra.verification_mode.get(i))) {
            AppConfig.setNfc(1, rootView.getContext());
          }
          if ("2".equals(rsp.extra.verification_mode.get(i))) {
            AppConfig.setFace(1, rootView.getContext());
            get(R.id.ll_face).setVisibility(View.VISIBLE);
          }
          if ("3".equals(rsp.extra.verification_mode.get(i))) {
            get(R.id.ll_qr_code).setVisibility(View.VISIBLE);
            AppConfig.setCode(1, rootView.getContext());
          }
        }
      }

    } else {
      get(R.id.ll_face).setVisibility(View.GONE);
      get(R.id.ll_qr_code).setVisibility(View.GONE);
      AppConfig.setCode(0, rootView.getContext());
      AppConfig.setNfc(0, rootView.getContext());
      AppConfig.setFace(0, rootView.getContext());
    }
    List<ModuleEntity> list = new ArrayList<>();
    list = rsp.extra.module;
    if (list != null && !list.isEmpty()) {
      BridgeWebView wv_service_1 = get(R.id.wv_service_1);
      get(R.id.wv_service_1).setVisibility(View.VISIBLE);
      setWebview1(wv_service_1, rsp.extra.module.get(0).module_url);
    } else {
      get(R.id.wv_service_1).setVisibility(View.GONE);
    }
  }

  private void setWebview1(BridgeWebView wv_service, String url) {
    wv_service.setDefaultHandler(new DefaultHandler());
    wv_service.setWebChromeClient(new MyWebChromeClient());
    wv_service.getSettings().setJavaScriptEnabled(true);
    wv_service.getSettings().setDomStorageEnabled(true);
    wv_service.clearCache(true);
    wv_service.clearHistory();
    wv_service.loadUrl(url);
    registerHandler(wv_service);
  }

  /**
   * 传值给h5
   *
   * @param wv_service_1
   */
  private void registerHandler(BridgeWebView wv_service_1) {
    wv_service_1.registerHandler("getDeviceInfo", (data, function) -> {
      JSONObject jsonObject = new JSONObject();
      try {
        jsonObject.put("school_id", ConfigDevice.school_id);
        jsonObject.put("imei", ConfigDevice.getDeviceId());
        Slog.i(TAG, "registerHandler: [shcool_id]" + ConfigDevice.school_id + "[imei]" + ConfigDevice.getDeviceId());
        function.onCallBack(jsonObject.toString());
      } catch (JSONException e) {
        e.printStackTrace();
      }
    });
  }


  /**
   * 更新课表
   *
   * @param mTodayZeroTime
   * @param mTodayWeek
   */
  public void updateTimeTables(long mTodayZeroTime, int mTodayWeek) {
   String type = SPUtils.getInstance(getActivity()).get("class_type", "1");
      TextView tvClassName = get(R.id.tv_class_type);
    if (type.equals("1")) {
      tvClassName.setText("课程名称");
    } else {
      tvClassName.setText("上课班级");
    }
    List<Timetables> timetables = KJDB.getDefaultInstance().findAllByWhere(Timetables.class, " week=" + mTodayWeek + " order by lesson asc");
    Timetables timetable = new Timetables();
    if (timetables.size() >4) {
      for (int i = 0; i < timetables.size(); i++) {
        if (timetables.get(i).lesson == 4) {
          timetable.name = "午休";
          timetable.starttime= "";
          timetable.endtime= "";
        }
      }
      timetables.add(4, timetable);
    }

    mClassList.clear();
    mClassList.addAll(timetables);
    mClassAdapter.setType(type);
    mClassAdapter.notifyDataChangedAfterLoadMore(false);

    loadClassInfo(mTodayZeroTime);
  }

  /**
   * 加载课表信息
   *
   * @param mTodayZeroTime
   */
  public void loadClassInfo(long mTodayZeroTime) {
    int classStartPos = getClassStartPos(mTodayZeroTime);
    int currentSelectPos = getCurrentSelectPos(mTodayZeroTime);
    mClassAdapter.setSelectPos(currentSelectPos);
//    if (classStartPos != -1 && classStartPos < mClassList.size()) {
//      get(R.id.show_time_layout).setVisibility(View.VISIBLE);
//      ((ClockView) get(R.id.show_time)).setEndTime((mTodayZeroTime + mClassList.get(classStartPos).start));
//    } else {
//      get(R.id.show_time_layout).setVisibility(View.GONE);
//    }
    if (currentSelectPos != 0 && currentSelectPos != -1) {
      ((RecyclerView) get(R.id.rv_class_list)).smoothScrollToPosition(currentSelectPos);
    }
    getActivity().runOnUiThread(() -> mClassAdapter.notifyDataChangedAfterLoadMore(false));
  }


  public final static int CLASS_START_COUNT_TIME = 600000;


  /**
   * 获取当前上课倒计时位置
   *
   * @param mTodayZeroTime
   * @return
   */
  private int getClassStartPos(long mTodayZeroTime) {
    if (null == mClassList || mClassList.size() == 0) {
      return -1;
    }
    for (int position = 0; position < mClassList.size(); position++) {
      Timetables item = mClassList.get(position);
      long startSubtractTime = mTodayZeroTime + item.start - System.currentTimeMillis();
      //当前
      if ((startSubtractTime > 0 && startSubtractTime <= CLASS_START_COUNT_TIME)) {
        return position;
      }
    }
    return -1;
  }

  /**
   * 获取当前选中的位置
   *
   * @param mTodayZeroTime
   * @return
   */
  private int getCurrentSelectPos(long mTodayZeroTime) {
    if (null == mClassList || mClassList.size() == 0) {
      return -1;
    }
    for (int position = 0; position < mClassList.size(); position++) {
      Timetables item = mClassList.get(position);
      long startSubtractTime = mTodayZeroTime + item.start - System.currentTimeMillis();
      long endSubtractTime = mTodayZeroTime + item.end - System.currentTimeMillis();
      //当前
      if ((startSubtractTime > 0 && startSubtractTime <= CLASS_START_COUNT_TIME) ||
          (startSubtractTime <= 0 && endSubtractTime >= 0)) {
        return position;
      }
    }
    return -1;
  }
}
